<a href='https://github.com/angular/angular.js/edit/v1.5.x/docs/content/tutorial/step_10.ngdoc?message=docs(tutorial%2F10 - More Templating)%3A%20describe%20your%20change...' class='improve-docs btn btn-primary'><i class="glyphicon glyphicon-edit">&nbsp;</i>Improve this Doc</a>


<ul doc-tutorial-nav="10"></ul>


<p>In this step, we will implement the phone details view, which is displayed when a user clicks on a
phone in the phone list.</p>
<ul>
<li>When you click on a phone on the list, the phone details page with phone-specific information is
displayed.</li>
</ul>
<p>To implement the phone details view we are going to use <a href="api/ng/service/$http">$http</a> to fetch our data,
and then flesh out the <code>phoneDetail</code> component&#39;s template.</p>
<div doc-tutorial-reset="10"></div>


<h2 id="data">Data</h2>
<p>In addition to <code>phones.json</code>, the <code>app/phones/</code> directory also contains one JSON file for each
phone:</p>
<p><br />
<strong><code>app/phones/nexus-s.json</code>:</strong> (sample snippet)</p>
<pre><code class="lang-json">{
  &quot;additionalFeatures&quot;: &quot;Contour Display, Near Field Communications (NFC), ...&quot;,
  &quot;android&quot;: {
    &quot;os&quot;: &quot;Android 2.3&quot;,
    &quot;ui&quot;: &quot;Android&quot;
  },
  ...
  &quot;images&quot;: [
    &quot;img/phones/nexus-s.0.jpg&quot;,
    &quot;img/phones/nexus-s.1.jpg&quot;,
    &quot;img/phones/nexus-s.2.jpg&quot;,
    &quot;img/phones/nexus-s.3.jpg&quot;
  ],
  &quot;storage&quot;: {
    &quot;flash&quot;: &quot;16384MB&quot;,
    &quot;ram&quot;: &quot;512MB&quot;
  }
}
</code></pre>
<p>Each of these files describes various properties of the phone using the same data structure. We will
show this data in the phone details view.</p>
<h2 id="component-controller">Component Controller</h2>
<p>We will expand the <code>phoneDetail</code> component&#39;s controller by using the <code>$http</code> service to fetch the
appropriate JSON files. This works the same way as the <code>phoneList</code> component&#39;s controller.</p>
<p><br />
<strong><code>app/phone-detail/phone-detail.component.js</code>:</strong></p>
<pre><code class="lang-js">angular.
  module(&#39;phoneDetail&#39;).
  component(&#39;phoneDetail&#39;, {
    templateUrl: &#39;phone-detail/phone-detail.template.html&#39;,
    controller: [&#39;$http&#39;, &#39;$routeParams&#39;,
      function PhoneDetailController($http, $routeParams) {
        var self = this;

        $http.get(&#39;phones/&#39; + $routeParams.phoneId + &#39;.json&#39;).then(function(response) {
          self.phone = response.data;
        });
      }
    ]
  });
</code></pre>
<p>To construct the URL for the HTTP request, we use <code>$routeParams.phoneId</code>, which is extracted from
the current route by the <code>$route</code> service.</p>
<h2 id="component-template">Component Template</h2>
<p>The inline, TBD placeholder template has been replaced with a full blown external template,
including lists and bindings that comprise the phone details. Note how we use the Angular
<code>{{expression}}</code> markup and <code>ngRepeat</code> to project phone data from our model into the view.</p>
<p><br />
<strong><code>app/phone-detail/phone-detail.template.html</code>:</strong></p>
<pre><code class="lang-html">&lt;img ng-src=&quot;{{$ctrl.phone.images[0]}}&quot; class=&quot;phone&quot; /&gt;

&lt;h1&gt;{{$ctrl.phone.name}}&lt;/h1&gt;

&lt;p&gt;{{$ctrl.phone.description}}&lt;/p&gt;

&lt;ul class=&quot;phone-thumbs&quot;&gt;
  &lt;li ng-repeat=&quot;img in $ctrl.phone.images&quot;&gt;
    &lt;img ng-src=&quot;{{img}}&quot; /&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;ul class=&quot;specs&quot;&gt;
  &lt;li&gt;
    &lt;span&gt;Availability and Networks&lt;/span&gt;
    &lt;dl&gt;
      &lt;dt&gt;Availability&lt;/dt&gt;
      &lt;dd ng-repeat=&quot;availability in $ctrl.phone.availability&quot;&gt;{{availability}}&lt;/dd&gt;
    &lt;/dl&gt;
  &lt;/li&gt;
  ...
  &lt;li&gt;
    &lt;span&gt;Additional Features&lt;/span&gt;
    &lt;dd&gt;{{$ctrl.phone.additionalFeatures}}&lt;/dd&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p><img class="diagram" src="img/tutorial/tutorial_10.png"></p>
<h1 id="testing">Testing</h1>
<p>We wrote a new unit test that is similar to the one we wrote for the <code>phoneList</code> component&#39;s
controller in <a href="tutorial/step_07#testing">step 7</a>.</p>
<p><br />
<strong><code>app/phone-detail/phone-detail.component.spec.js</code>:</strong></p>
<pre><code class="lang-js">describe(&#39;phoneDetail&#39;, function() {

  // Load the module that contains the `phoneDetail` component before each test
  beforeEach(module(&#39;phoneDetail&#39;));

  // Test the controller
  describe(&#39;PhoneDetailController&#39;, function() {
    var $httpBackend, ctrl;

    beforeEach(inject(function($componentController, _$httpBackend_, $routeParams) {
      $httpBackend = _$httpBackend_;
      $httpBackend.expectGET(&#39;phones/xyz.json&#39;).respond({name: &#39;phone xyz&#39;});

      $routeParams.phoneId = &#39;xyz&#39;;

      ctrl = $componentController(&#39;phoneDetail&#39;);
    }));

    it(&#39;should fetch the phone details&#39;, function() {
      expect(ctrl.phone).toBeUndefined();

      $httpBackend.flush();
      expect(ctrl.phone).toEqual({name: &#39;phone xyz&#39;});
    });

  });

});
</code></pre>
<p>You should now see the following output in the Karma tab:</p>
<pre><code>Chrome 49.0: Executed 3 of 3 SUCCESS (0.159 secs / 0.136 secs)
</code></pre>
<p>We also added a new E2E test that navigates to the &#39;Nexus S&#39; details page and verifies that the
heading on the page is &quot;Nexus S&quot;.</p>
<p><br />
<strong><code>e2e-tests/scenarios.js</code></strong></p>
<pre><code class="lang-js">...

describe(&#39;View: Phone detail&#39;, function() {

  beforeEach(function() {
    browser.get(&#39;index.html#!/phones/nexus-s&#39;);
  });

  it(&#39;should display the `nexus-s` page&#39;, function() {
    expect(element(by.binding(&#39;$ctrl.phone.name&#39;)).getText()).toBe(&#39;Nexus S&#39;);
  });

});

...
</code></pre>
<p>You can run the tests with <code>npm run protractor</code>.</p>
<h1 id="experiments">Experiments</h1>
<div></div>

<ul>
<li>Using <a href="https://angular.github.io/protractor/#/api">Protractor&#39;s API</a>, write a test that verifies that we display 4 thumbnail
images on the &#39;Nexus S&#39; details page.</li>
</ul>
<h1 id="summary">Summary</h1>
<p>Now that the phone details view is in place, proceed to <a href="tutorial/step_11">step 11</a> to learn how to
write your own custom display filter.</p>
<ul doc-tutorial-nav="10"></ul>





